package com.shensi.adminCollect.service.station.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shensi.common.core.domain.entity.SysUser;
import com.shensi.common.core.utils.SecurityUtils;
import com.shensi.adminCollect.domain.station.ReceiptSection;
import com.shensi.adminCollect.domain.station.ReceiptSectionField;
import com.shensi.adminCollect.domain.station.vo.ReceiptContentVO;
import com.shensi.adminCollect.enums.station.ReceiptType;
import com.shensi.adminCollect.mapper.station.ReceiptSectionMapper;
import com.shensi.adminCollect.service.station.IReceiptSectionFieldService;
import com.shensi.adminCollect.service.station.IReceiptSectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @date 2024/1/23
 */
@Service
public class ReceiptSectionServiceImpl extends ServiceImpl<ReceiptSectionMapper, ReceiptSection> implements IReceiptSectionService {

    private static final String PAGE_TAIL_NAME = "pageTail";

    public static final long DEFAULT_ENTERPRISE_ID = 0L;

    @Autowired
    private IReceiptSectionFieldService receiptSectionFieldService;

    @Override
    public List<ReceiptSection> queryAllReceiptSectionWithField(Long enterpriseId, ReceiptType receiptType) {
        LambdaQueryWrapper<ReceiptSection> receiptSectionQw = Wrappers.lambdaQuery(ReceiptSection.class);
        receiptSectionQw.eq(ReceiptSection::getReceiptType, receiptType)
                .and(i -> i.eq(ReceiptSection::getEnterpriseId, enterpriseId).or().eq(ReceiptSection::getEnterpriseId, DEFAULT_ENTERPRISE_ID))
                .orderByAsc(ReceiptSection::getEnterpriseId);
        List<ReceiptSection> sectionList = this.list(receiptSectionQw);
        sectionList = new ArrayList<>(sectionList.stream().collect(Collectors.toMap(ReceiptSection::getSectionName, re -> re, (u, v) -> v, HashMap::new)).values());
        sectionList.sort(Comparator.comparingInt(ReceiptSection::getSectionOrder));
        LambdaQueryWrapper<ReceiptSectionField> receiptSectionFieldQw = Wrappers.lambdaQuery(ReceiptSectionField.class);
        receiptSectionFieldQw.eq(ReceiptSectionField::getReceiptType, receiptType)
                .and(i -> i.eq(ReceiptSectionField::getEnterpriseId, enterpriseId).or().eq(ReceiptSectionField::getEnterpriseId, DEFAULT_ENTERPRISE_ID))
                .orderByAsc(ReceiptSectionField::getEnterpriseId);
        List<ReceiptSectionField> fieldList = receiptSectionFieldService.list(receiptSectionFieldQw);
        Map<String, List<ReceiptSectionField>> filedsMap = fieldList.stream()
                .collect(Collectors.toMap(rf -> rf.getSectionName() + rf.getFieldName(), rf -> rf, (u, v) -> v, HashMap::new))
                .values()
                .stream()
                .sorted(Comparator.comparingInt(ReceiptSectionField::getFieldOrder))
                .collect(Collectors.groupingBy(ReceiptSectionField::getSectionName,
                        Collectors.mapping(rf -> {
                            if (rf.getEnterpriseId() == 0) {
                                rf.setId(null);
                                rf.setEnterpriseId(null);
                                rf.setSectionId(null);
                            }
                            return rf;
                        }, Collectors.toList())));
        for (ReceiptSection receiptSection : sectionList) {
            receiptSection.setFieldList(filedsMap.get(receiptSection.getSectionName()));
            if (receiptSection.getEnterpriseId() == 0) {
                receiptSection.setId(null);
                receiptSection.setEnterpriseId(null);
            }
        }
        return sectionList;
    }

    @Override
    public ReceiptContentVO queryListWithDefault(Long enterpriseId, ReceiptType receiptType) {
        if (enterpriseId == null) {
            return null;
        }
        List<ReceiptSection> receiptSections = this.queryAllReceiptSectionWithField(enterpriseId, receiptType);
        ReceiptContentVO contentVO = new ReceiptContentVO();
        contentVO.setEnterpriseId(enterpriseId);
        contentVO.setReceiptType(receiptType);
        contentVO.setSectionList(receiptSections);
        return contentVO;
    }

    @Override
    public ReceiptContentVO queryDefaultList(Long enterpriseId, ReceiptType receiptType) {
        if (enterpriseId == null) {
            return null;
        }
        List<ReceiptSection> receiptSections = this.queryAllReceiptSectionWithField(enterpriseId, receiptType);
        List<ReceiptSection> defaultReceiptSections = this.queryAllReceiptSectionWithField(DEFAULT_ENTERPRISE_ID, receiptType);
        Map<String, ReceiptSection> rsMap = receiptSections.stream().collect(Collectors.toMap(ReceiptSection::getSectionName, rs -> rs));
        for (ReceiptSection defaultRs : defaultReceiptSections) {
            ReceiptSection rs = rsMap.get(defaultRs.getSectionName());
            if (rs == null) {
                continue;
            }
            defaultRs.setId(rs.getId());
            defaultRs.setEnterpriseId(rs.getEnterpriseId());
            Map<String, ReceiptSectionField> rfMap = rs.getFieldList().stream().collect(Collectors.toMap(rf -> rf.getSectionName() + rf.getFieldName(), rf -> rf));
            List<ReceiptSectionField> defRfList = defaultRs.getFieldList();
            for (ReceiptSectionField defRf : defRfList) {
                ReceiptSectionField rf = rfMap.get(defRf.getSectionName() + defRf.getFieldName());
                if (rf == null) {
                    continue;
                }
                defRf.setId(rf.getId());
                defRf.setSectionId(rf.getSectionId());
                defRf.setEnterpriseId(rf.getEnterpriseId());
            }
        }
        ReceiptContentVO contentVO = new ReceiptContentVO();
        contentVO.setEnterpriseId(enterpriseId);
        contentVO.setReceiptType(receiptType);
        contentVO.setSectionList(defaultReceiptSections);
        return contentVO;
    }

    @Override
    @Transactional
    public void save(ReceiptContentVO contentVO) {
        SysUser sysUser = SecurityUtils.getLoginSysUser();
        Long enterpriseId = sysUser.getEnterpriseId();
        if (enterpriseId == null) {
            return;
        }
//        LambdaQueryWrapper<ReceiptSection> receiptSectionQw = Wrappers.lambdaQuery(ReceiptSection.class);
//        receiptSectionQw.eq(ReceiptSection::getEnterpriseId, enterpriseId)
//                        .eq(ReceiptSection::getReceiptType,contentVO.getReceiptType());
//        List<ReceiptSection> sectionList = this.list(receiptSectionQw);
//        if (CollectionUtils.isNotEmpty(sectionList)) {
//            this.remove(receiptSectionQw);
//            Stream<Long> sectionIds = sectionList.stream().map(ReceiptSection::getId);
//            LambdaQueryWrapper<ReceiptSectionField> receiptSectionFieldQw = Wrappers.lambdaQuery(ReceiptSectionField.class);
//            receiptSectionFieldQw.eq(ReceiptSectionField::getEnterpriseId, enterpriseId).in(ReceiptSectionField::getSectionId,sectionIds);
//            receiptSectionFieldService.remove(receiptSectionFieldQw);
//        }
        List<ReceiptSection> sectionList1 = contentVO.getSectionList();
        int i = -1;
        LocalDateTime now = LocalDateTime.now();
        String userIdStr = String.valueOf(sysUser.getUserId());
        for (ReceiptSection receiptSection : sectionList1) {
            i++;
            receiptSection.setEnterpriseId(enterpriseId);
            receiptSection.setReceiptType(contentVO.getReceiptType());
            receiptSection.setSectionOrder(i);
            if (receiptSection.getId() == null) {
                receiptSection.setCreateTime(now);
                receiptSection.setCreateBy(userIdStr);
                save(receiptSection);
            } else {
                receiptSection.setUpdateTime(now);
                receiptSection.setUpdateBy(userIdStr);
                updateById(receiptSection);
            }
            List<ReceiptSectionField> fieldList = receiptSection.getFieldList();
            int j = -1;
            for (ReceiptSectionField receiptSectionField : fieldList) {
                j++;
                receiptSectionField.setEnterpriseId(enterpriseId);
                receiptSectionField.setReceiptType(contentVO.getReceiptType());
                receiptSectionField.setSectionName(receiptSection.getSectionName());
                receiptSectionField.setSectionId(receiptSection.getId());
                receiptSectionField.setFieldOrder(j);
                if (receiptSectionField.getId() == null) {
                    receiptSectionField.setCreateTime(now);
                    receiptSectionField.setCreateBy(userIdStr);
                    receiptSectionFieldService.save(receiptSectionField);
                } else {
                    receiptSectionField.setUpdateTime(now);
                    receiptSectionField.setUpdateBy(userIdStr);
                    receiptSectionFieldService.updateById(receiptSectionField);
                }
            }
        }
    }

}
